#include "../log.h"

u32 profiler[20] = {0};
char *profname[] = {
    "systemck",       "cpuck",         "stall (total)",  "stall (internal)",
    "stall (memory)", "stall (COPz)",  "stall (VFPU)",   "sleep",
    "bus access",     "uncached load", "uncached store", "cached load",
    "cached store",   "I cache miss",  "D cache miss",   "D cache wb",
    "COP0 inst",      "FPU inst",      "VFPU inst",      "local bus"
};
u8 profenabled = 0;

s32 prof_read(u32 address)
{
    u32 code;
    if (address > 0xbc400050) {
        _log(ERR, HARDWARE, "Profiler (read): unknown profiler address %08x!", address);
        return -1;
    }

    code = address - 0xbc400000;

    if (code % 4 != 0) {
        _log(ERR, HARDWARE, "Profiler (read): address %08x is not a 4 multiple??", address);
        return -1;
    }

    code /= 4;

    if (code == 0) {
        _log(INF, HARDWARE, "Profiler: read %d for enabled state", profenabled);
        return profenabled;
    }
    else
    {
        code -= 1;
        _log(INF, HARDWARE, "Profiler: read %d for %s", profiler[code], profname[code]);
        return profiler[code];
    }
}

void prof_write(u32 address, u32 value)
{
    u32 code;
    if (address > 0xbc400050) {
        _log(ERR, HARDWARE, "Profiler (write): unknown profiler address %08x!", address);
        return;
    }

    code = address - 0xbc400000;

    if (code % 4 != 0) {
        _log(ERR, HARDWARE, "Profiler (write): address %08x is not a 4 multiple??", address);
        return;
    }

    code /= 4;

    if (code == 0)
    {
        if ((value & 1) == 0) {
            _log(INF, HARDWARE, "Profiler disabled");
            profenabled = 0;
        }
        else {
            _log(INF, HARDWARE, "Profiler enabled");
            profenabled = 1;
        }
    }
    else
    {
        code -= 1;
        if (value == 0) {
            _log(INF, HARDWARE, "Profiler: %s reset to 0", profname[code]);
            profiler[code] = 0;
        }
        else
            _log(ERR, HARDWARE, "Profiler: hand-set %d value for %s??", value, profname[code]);
    }
}

